// Package tools 提供一些常用的工具函数
package tools

import "reflect"

// DelSliceItem 从 slice 中删除特定的元素，保持元素顺序不变
//
// 参数:
//   - slice: 要操作的切片
//   - isDelete: 一个函数，用于判断某个下标的元素是否需要删除
//
// 返回值:
//   - interface{}: 删除对应元素后的 slice，调用方需要断言为具体类型
func DelSliceItem(slice interface{}, isDelete func(index int) bool) interface{} {
	sliceValue := reflect.ValueOf(slice)
	if sliceValue.Kind() != reflect.Slice {
		panic("参数类型必须是 slice")
	}

	length := sliceValue.Len()
	count := 0
	for i := 0; i < length; i++ {
		if isDelete(i) {
			continue
		}

		if count < i {
			reflect.Swapper(slice)(count, i)
		}

		count++
	}

	return sliceValue.Slice(0, count).Interface()
}

// SlicesUnion 求两个字符串切片的并集
//
// 参数:
//   - slice1: 第一个字符串切片
//   - slice2: 第二个字符串切片
//
// 返回值:
//   - []string: 并集结果
func SlicesUnion(slice1, slice2 []string) []string {
	m := make(map[string]struct{})

	for _, v := range slice1 {
		m[v] = struct{}{}
	}

	for _, v := range slice2 {
		if _, ok := m[v]; !ok {
			slice1 = append(slice1, v)
		}
	}

	return slice1
}

// SlicesIntersect 求两个字符串切片的交集
//
// 参数:
//   - slice1: 第一个字符串切片
//   - slice2: 第二个字符串切片
//
// 返回值:
//   - []string: 交集结果
func SlicesIntersect(slice1, slice2 []string) []string {
	m := make(map[string]struct{})
	nn := make([]string, 0)

	for _, v := range slice1 {
		m[v] = struct{}{}
	}

	for _, v := range slice2 {
		if _, ok := m[v]; ok {
			nn = append(nn, v)
		}
	}

	return nn
}
